{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bd2b2eba-b7fd-4856-960f-f2cbadcc12af",
   "metadata": {},
   "source": [
    "# Building a Exa (formerly Metaphor) Data Agent\n",
    "\n",
    "<a href=\"https://colab.research.google.com/github/run-llama/llama-hub/blob/main/llama_hub/tools/notebooks/exa.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
    "\n",
    "This tutorial walks through using the LLM tools provided by the [Exa API](https://exa.ai) to allow LLMs to easily search and retrieve HTML content from the Internet.\n",
    "\n",
    "To get started, you will need an [OpenAI api key](https://platform.openai.com/account/api-keys) and an [Exa API key](https://dashboard.exa.ai/overview)\n",
    "\n",
    "We will import the relevant agents and tools and pass them our keys here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6a53dd54-e816-43c8-a3c0-069c397c10e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install exa_py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df2a0ecd-22e9-4cef-b069-89e4286e4d75",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "search\n",
      "retrieve_documents\n",
      "search_and_retrieve_documents\n",
      "search_and_retrieve_highlights\n",
      "find_similar\n",
      "current_date\n"
     ]
    }
   ],
   "source": [
    "# Set up OpenAI\n",
    "import os\n",
    "import openai\n",
    "from llama_index.agent import OpenAIAgent\n",
    "\n",
    "openai.api_key = os.environ[\"OPENAI_API_KEY\"]\n",
    "\n",
    "# Set up Metaphor tool\n",
    "from llama_hub.tools.exa.base import ExaToolSpec\n",
    "\n",
    "exa_tool = ExaToolSpec(\n",
    "    api_key=os.environ[\"EXA_API_KEY\"],\n",
    "    # max_characters=2000   # this is the default\n",
    ")\n",
    "\n",
    "exa_tool_list = exa_tool.to_tool_list()\n",
    "for tool in exa_tool_list:\n",
    "    print(tool.metadata.name)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe8e3012-bab0-4e55-858a-e3721282552c",
   "metadata": {},
   "source": [
    "## Testing the Exa tools\n",
    "\n",
    "We've imported our OpenAI agent, set up the api key, and initialized our tool, checking the methods that it has available. Let's test out the tool before setting up our Agent.\n",
    "\n",
    "All of the Exa search tools make use of the `AutoPrompt` option where Exa will pass the query through an LLM to refine and improve it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e64da618-b4ab-42d7-903d-f4eeb624f43c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Exa Tool] Autoprompt: Here is a link to an article about machine learning transformers:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(id_='a2eef546-811c-4bbf-bfe0-1c7fd7fe526d', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, hash='b846333f5fffd9a45abfcb16388bb7192676eee95333ff623321c092c24d5bb2', text='\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n December 18, 2021\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n 7 minute read\\n \\n \\n \\n \\n \\n \\n \\n \\n \\nSummary\\nTransformers architectures are the hottest thing in supervised and unsupervised learning, achieving SOTA results on natural language processing, vision, audio and multimodal tasks. Their key capability is to capture which elements in a long sequence are worthy of attention, resulting in great summarisation and generative skills. Can we transfer any of these skills to reinforcement learning? The ans', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n'),\n",
       " Document(id_='174bd84d-6913-43cd-b193-b807bfd1f6b8', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, hash='cd1041b5e04c3b476f1737818579c80820cb35d0d7573d25c9c48abb5bee008f', text='<div><div><h2>Machine Learning Theory</h2><div><h2>The Model Responsible for your Siri, Alexa and Google Home</h2><div><a href=\"https://diegounzuetaruedas.medium.com/?source=post_page-----cdd7961eef84--------------------------------\"><div><p></p></div></a><a href=\"https://towardsdatascience.com/?source=post_page-----cdd7961eef84--------------------------------\"><div><p></p></div></a></div></div><figure><figcaption>Image by Author</figcaption></figure><p>Transformers have revolutionized the field', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n'),\n",
       " Document(id_='87070de8-fc49-4f86-ab8f-6dadf6b4dcc5', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, hash='1379dd71e7af4983def3384acebd57645fb2a0ae4b7fd8c9bba9127a10075d53', text='Hands-on TutorialsThis article aims to introduce/refresh the main ideas behind Transformers and to present the latest advancements on using these models for Computer Vision applications.After reading this article you will know…… why Transformers outperformed SOTA models in NLP tasks.… how the Transformer model works at a glance.… which are the main limitations of convolutional models.… how Transformers can overcome limitations in convolutional models.… how novel works use Transformers for Comput', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exa_tool.search_and_retrieve_documents(\"machine learning transformers\", num_results=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c55a0c7b-4c58-4725-8543-29bb1b7278ed",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'title': 'A Deep Dive Into the Transformer Architecture — The Development of Transformer Models',\n",
       "  'url': 'https://towardsdatascience.com/a-deep-dive-into-the-transformer-architecture-the-development-of-transformer-models-acbdf7ca34e0?gi=b4d77d2ab4db',\n",
       "  'id': '60J3eIu_oZO9OEulMglxuw'},\n",
       " {'title': 'What is a Transformer?',\n",
       "  'url': 'https://medium.com/inside-machine-learning/what-is-a-transformer-d07dd1fbec04',\n",
       "  'id': 'uxGX5rLD8HXrmgQiyQIYyw'},\n",
       " {'title': 'The Transformer Model',\n",
       "  'url': 'https://towardsdatascience.com/attention-is-all-you-need-e498378552f9?gi=92758857966b',\n",
       "  'id': 'RKL4_dd9kKX_OThZCXo8Yg'}]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exa_tool.find_similar(\n",
    "    \"https://www.mihaileric.com/posts/transformers-attention-in-disguise/\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1fc8665d-ddb8-411f-b187-93a132d19e7a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Exa Tool] Autoprompt: Here is a recent research paper about diffusion models:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(id_='556c9b58-67d1-470a-b03a-1596d1d6c7dd', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text='Diffusion Models Beat GANs on Image Synthesis\\n\\nDate Published: 2021-06-01\\n\\nAuthors:\\nPrafulla  Dhariwal, prafulla@openai.com\\nAlex  Nichol\\n\\nAbstract\\n\\nWe show that diffusion models can achieve image sample quality superior to the current state-of-the-art generative models. We achieve this on unconditional image synthesis by finding a better architecture through a series of ablations. For conditional image synthesis, we further improve sample quality with classifier guidance: a simple, compute-efficient method for trading off diversity for fidelity using gradients from a classifier. We achieve an FID of 2.97 on ImageNet 128×128, 4.59 on ImageNet 256×256, and 7.72 on ImageNet 512×512, and we match BigGAN-deep even with as few as 25 forward passes per sample, all while maintaining better coverage of the distribution. Finally, we find that classifier guidance combines well with upsampling diffusion models, further improving FID to 3.94 on ImageNet 256×256 and 3.85 on ImageNet 512×512. We release our code at https://github.com/openai/guided-diffusion.\\n\\n1 Introduction\\n\\nOver the past few years, generative models have gained the ability to generate human-like natural language [6] , infinite high-quality synthetic images [5, 28, 51] and highly diverse human speech and music [64, 13] . These models can be used in a variety of ways, such as generating images from text prompts [72, 50] or learning useful feature representations [14, 7] . While these models are already capable of producing realistic images and sound, there is still much room for improvement beyond the current state-of-the-art, and better generative models could have wide-ranging impacts on graphic design, games, music production, and countless other fields.\\n\\nGANs [19] currently hold the state-of-the-art on most image generation tasks [5, 68, 28] as measured by sample quality metrics such as FID [23] , Inception Score [54] and Precision [32] . However, some of these metrics do not fully capture diversity, and it has', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exa_tool.search_and_retrieve_documents(\n",
    "    \"This is a summary of recent research around diffusion models:\", num_results=1\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9325841-9f9a-4b9e-a602-fe542be8f364",
   "metadata": {},
   "source": [
    "While `search_and_retrieve_documents` returns raw text from the source document, `search_and_retrieve_highlights` returns relevant curated snippets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a64b37f6-ec12-45e8-9291-fa2fe51de311",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Exa Tool] Autoprompt: Here is a research paper about diffusion models that you might find useful:\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(id_='695ad95b-edd8-4083-ad16-512203d43f9a', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text='On a high level, diffusion models sample from a distribution by reversing a gradual noising process. In particular, sampling starts with noise x T and produces gradually less-noisy samples x T -1 , x T -2 , ... until reaching a final sample x 0 . Each timestep t corresponds to a certain noise level, and x t can be thought of as a mixture of a signal x 0 with some noise where the signal to noise ratio is determined by the timestep t. For the remainder of this paper, we assume that the noise is drawn from a diagonal Gaussian distribution, which works well for natural images and simplifies various derivations. A diffusion model learns to produce a slightly more \"denoised\" x t-1 from x t .', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exa_tool.search_and_retrieve_highlights(\n",
    "    \"This is a summary of recent research around diffusion models:\", num_results=1\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1210906d-87a7-466a-9712-1d17dba2c2ec",
   "metadata": {},
   "source": [
    "We can see we have different tools to search for results, retrieve the results, find similar results to a web page, and finally a tool that combines search and document retrieval into a single tool. We will test them out in LLM Agents below:\n",
    "\n",
    "### Using the Search and Retrieve documents tools in an Agent\n",
    "\n",
    "We can create an agent with access to the above tools and start testing it out:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d88c2ee-184a-4371-995b-a086b34db24f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# We don't give the Agent our unwrapped retrieve document tools, instead passing the wrapped tools\n",
    "agent = OpenAIAgent.from_tools(\n",
    "    exa_tool_list,\n",
    "    verbose=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f69a53fd-55c4-4e18-8fbe-6a29d5f3cef0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added user message to memory: What are the best resturants in toronto?\n",
      "=== Calling Function ===\n",
      "Calling function: search with args: {\n",
      "  \"query\": \"best restaurants in Toronto\"\n",
      "}\n",
      "[Exa Tool] Autoprompt: Here's a great restaurant to try in Toronto:\n",
      "Got output: [{'title': 'PATOIS • TORONTO', 'url': 'https://www.patoistoronto.com/', 'id': '5EC2l7fbaPoEydNVNwjc-A'}, {'title': 'Location', 'url': 'https://osteriagiulia.ca/', 'id': 'mpjelsyCOpNipFFI5AoZTQ'}, {'title': 'Enigma Yorkville | Modern European Restaurant in Toronto, ON', 'url': 'https://www.enigmayorkville.com/', 'id': 'jBOC2QfhTfuPjt0YdibEVA'}, {'title': 'GOA | by Hemant Bhagwani', 'url': 'https://www.goatoronto.ca/', 'id': 'e8sCvTX5NVVbwzoOr0o6aw'}, {'title': 'Portuguese inspired seafood from around the world | Adega Restaurante', 'url': 'https://adegarestaurante.ca/', 'id': 'oQiAWWgzrU-ryPNmgj3UuA'}, {'title': 'Home', 'url': 'https://www.avelorestaurant.com/', 'id': 'NDfST6oMKpJ0I-VYUf_WHA'}, {'title': 'PAI Northern Thai Kitchen', 'url': 'https://www.paitoronto.com/', 'id': 'aP7DB4WaZWCfqoGNeqJ4Kw'}, {'title': 'Oretta | Toronto, ON', 'url': 'https://www.oretta.to/', 'id': 'pSN1mTBx5hQ3R-aeXKrOug'}, {'title': 'Welcome to \"Woodlot Toronto\" restaurant! - Woodlot Toronto', 'url': 'https://woodlottoronto.com/', 'id': 'VUKoFW1gttmNySwHYhlgJw'}, {'title': 'Discover Opus Restaurant', 'url': 'https://www.opusrestaurant.com/#home', 'id': 'mCJBZ9lAxM2jouP0vcdbxA'}]\n",
      "========================\n",
      "\n",
      "Here are some of the best restaurants in Toronto:\n",
      "\n",
      "1. [PATOIS • TORONTO](https://www.patoistoronto.com/)\n",
      "2. [Osteria Giulia](https://osteriagiulia.ca/)\n",
      "3. [Enigma Yorkville | Modern European Restaurant](https://www.enigmayorkville.com/)\n",
      "4. [GOA | by Hemant Bhagwani](https://www.goatoronto.ca/)\n",
      "5. [Adega Restaurante](https://adegarestaurante.ca/)\n",
      "6. [Alo Restaurant](https://www.alorestaurant.com/)\n",
      "7. [PAI Northern Thai Kitchen](https://www.paitoronto.com/)\n",
      "8. [Oretta](https://www.oretta.to/)\n",
      "9. [Woodlot Toronto](https://woodlottoronto.com/)\n",
      "10. [Opus Restaurant](https://www.opusrestaurant.com/#home)\n",
      "\n",
      "Please note that these are just a few recommendations and there are many more amazing restaurants in Toronto.\n"
     ]
    }
   ],
   "source": [
    "print(agent.chat(\"What are the best resturants in toronto?\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f44035e9-27ab-47b7-abc5-cf2fe5d1482f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added user message to memory: tell me more about Osteria Giulia\n",
      "=== Calling Function ===\n",
      "Calling function: retrieve_documents with args: {\n",
      "  \"ids\": [\"mpjelsyCOpNipFFI5AoZTQ\"]\n",
      "}\n",
      "Got output: Error: 'results'\n",
      "========================\n",
      "\n",
      "=== Calling Function ===\n",
      "Calling function: search with args: {\n",
      "  \"query\": \"Osteria Giulia Toronto\"\n",
      "}\n",
      "[Exa Tool] Autoprompt: Here's a great Italian restaurant in Toronto called Osteria Giulia:\n",
      "Got output: [{'title': 'Giulietta', 'url': 'https://giu.ca/', 'id': 'GWjEUcgDP26STPskrgMM5g'}, {'title': 'Location', 'url': 'https://osteriagiulia.ca/', 'id': 'mpjelsyCOpNipFFI5AoZTQ'}, {'title': 'Gusto 501', 'url': 'https://www.restaurantji.com/on/toronto/gusto-501-/', 'id': 'Oa5NvNXMnweapgE1tO8WYQ'}, {'title': 'Menu - Gia Restaurant', 'url': 'https://giarestaurant.ca/', 'id': '35CymOCvS59-Lmdilq5XLw'}, {'title': 'Osteria Ilaria', 'url': 'https://www.osteriailaria.com/', 'id': 'SN6NKvpXluVgWCv5GPI88Q'}, {'title': 'Osteria Fortunato', 'url': 'https://osteriafortunato.ca/', 'id': 'MC6pGvtQMnb6IueV5navRg'}, {'title': 'King West | Oretta | Toronto, ON', 'url': 'https://www.oretta.to/kingwest/home', 'id': 'qddpWk4WMhFHzwQNjX_M9w'}, {'title': 'Oretta | Toronto, ON', 'url': 'https://www.oretta.to/', 'id': 'pSN1mTBx5hQ3R-aeXKrOug'}, {'title': 'Giulietta - Pizzeria Napoletana', 'url': 'https://www.giuliettapizzeria.ca/', 'id': '4Zj0Mk2X_FZ3BdQvPw79RQ'}, {'title': None, 'url': 'https://osteriapazzia.blogspot.com/', 'id': 'VhpAyEf3ieGxM0CsCdw6WA'}]\n",
      "========================\n",
      "\n",
      "Osteria Giulia is an Italian restaurant located in Toronto. Unfortunately, I couldn't find specific information about Osteria Giulia in the available search results. However, I found some related information that might be of interest:\n",
      "\n",
      "1. [Giulietta](https://giu.ca/): Giulietta is another Italian restaurant in Toronto that you might want to check out.\n",
      "\n",
      "2. [Gusto 501](https://www.restaurantji.com/on/toronto/gusto-501-/): Gusto 501 is a restaurant located in Toronto that offers Italian cuisine.\n",
      "\n",
      "3. [Gia Restaurant](https://giarestaurant.ca/): Gia Restaurant is another Italian restaurant in Toronto that you might want to explore.\n",
      "\n",
      "4. [Osteria Ilaria](https://www.osteriailaria.com/): Osteria Ilaria is an Italian restaurant located in Vancouver, British Columbia.\n",
      "\n",
      "5. [Osteria Fortunato](https://osteriafortunato.ca/): Osteria Fortunato is an Italian restaurant located in Toronto.\n",
      "\n",
      "6. [Oretta](https://www.oretta.to/kingwest/home): Oretta is an Italian restaurant located in Toronto.\n",
      "\n",
      "7. [Giulietta - Pizzeria Napoletana](https://www.giuliettapizzeria.ca/): Giulietta is a pizzeria in Toronto that specializes in Neapolitan-style pizza.\n",
      "\n",
      "Please note that the information provided is based on the search results and may not directly pertain to Osteria Giulia. It is recommended to visit the official website or contact the restaurant directly for more accurate and up-to-date information.\n"
     ]
    }
   ],
   "source": [
    "print(agent.chat(\"tell me more about Osteria Giulia\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "939c7b98-0d75-4ef0-ac47-fd3bd24d3e50",
   "metadata": {},
   "source": [
    "## Avoiding Context Window Issues\n",
    "\n",
    "The above example shows the core uses of the Exa tool. We can easily retrieve a clean list of links related to a query, and then we can fetch the content of the article as a cleaned up html extract. Alternatively, the search_and_retrieve_documents tool directly returns the documents from our search result.\n",
    "\n",
    "We can see that the content of the articles is somewhat long and may overflow current LLM context windows.  \n",
    "\n",
    "1. Use `search_and_retrieve_highlights`: This is an endpoint offered by Exa that directly retrieves relevant highlight snippets from the web, instead of full web articles. As a result you don't need to worry about indexing/chunking offline yourself!\n",
    "\n",
    "2. Wrap `search_and_retrieve_documents` with `LoadAndSearchToolSpec`: We set up and use a \"wrapper\" tool from LlamaIndex that allows us to load text from any tool into a VectorStore, and query it for retrieval. This is where the `search_and_retrieve_documents` tool become particularly useful. The Agent can make a single query to retrieve a large number of documents, using a very small number of tokens, and then make queries to retrieve specific information from the documents."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b8c51fc-8a22-408e-94c9-14248bad61c1",
   "metadata": {},
   "source": [
    "### 1. Using `search_and_retrieve_highlights`\n",
    "\n",
    "The easiest is to just use `search_and_retrieve_highlights` from Exa. This is essentially a \"web RAG\" endpoint - they handle chunking/embedding under the hood."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "197d241b-cd53-4038-a824-d493c69166b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = exa_tool.to_tool_list(\n",
    "    spec_functions=[\"search_and_retrieve_highlights\", \"current_date\"]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c412501-4fa3-4bb5-a324-075e809737d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = OpenAIAgent.from_tools(\n",
    "    tools,\n",
    "    verbose=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "242c779e-9dbc-4aec-8838-c152bf8f304b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Added user message to memory: Tell me more about the recent news on semiconductors\n",
      "=== Calling Function ===\n",
      "Calling function: current_date with args: {}\n",
      "Got output: 2024-01-25\n",
      "========================\n",
      "\n",
      "=== Calling Function ===\n",
      "Calling function: search_and_retrieve_highlights with args: {\n",
      "  \"query\": \"semiconductors\",\n",
      "  \"num_results\": 5,\n",
      "  \"start_published_date\": \"2024-01-01\",\n",
      "  \"end_published_date\": \"2024-01-25\"\n",
      "}\n",
      "[Exa Tool] Autoprompt: \"Here is an informative resource about semiconductors:\n",
      "Got output: [Document(id_='e72b143e-df3a-408e-b790-24a3931b18da', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text='<p>Semiconductors are crucial for multiple applications in electronics, communications, automotive, agriculture, healthcare, finance, and energy. After a slight turmoil phase during 2023, it is expected that the chip industry will exhibit a strong recovery and thrive this year and beyond.</p><p>According to the latest forecast by the World Semiconductor Trade Statistics (WSTS), the global semiconductor market is anticipated to <a href=\"https://www.wsts.org/76/Recent-News-Release\">reach a valuation of $588 billion in 2024</a>, indicating a growth of 13.1%. This growth will be primarily fuelled by the Memory sector, which is on track to surge to nearly $130 billion this year, up an impressive 40% from the prior year.</p> <p>The <a href=\"https://www.citigroup.com/global/insights/global-insights/the-u-s-china-chip-war-who-dares-to-win\">U.S.-China chips rivalry</a> has pushed the economy to take some serious steps to advance in-house chip manufacturing.', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n'), Document(id_='55de1b8b-d50a-4226-8f12-d03523681154', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text=\" VC investment in the semiconductor vertical has been on a downward trajectory. Despite major policy shifts and renewed public interest, it declined in 2023 to a total of $10.3 billion, compared with 2022's $12.8 billion and 2021’s peak of $16.1 billion. With China eating up a record amount of VC dollars, what’s in store for the vertical is up in the air, but our latest Emerging Tech Research dives into the key trends and opportunities around semiconductors.  By clicking “Accept All Cookies”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts.\", start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n'), Document(id_='9cb57f41-bb3b-4f5e-bbc3-2c53955da825', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text='A band gap is a material that can be turned on and off when an electric field is applied to it, which is how all transistors and silicon electronics work. The major question in graphene electronics research was how to switch it on and off so it can work like silicon.</p><p>But to make a functional transistor, a semiconducting material must be greatly manipulated, which can damage its properties. To prove that their platform could function as a viable semiconductor, the team needed to measure its electronic properties without damaging it.</p><p>They put atoms on the graphene that \"donate\" electrons to the system — a technique called doping, used to see whether the material was a good conductor. It worked without damaging the material or its properties.', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n'), Document(id_='c7f49648-2dcf-4e6d-85c0-8e44e8f7ec3f', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text=\"These companies aren't talked about as much as Nvidia, AMD, or Intel, but they play an increasingly important role in the industry. *Stock prices used were from the trading day of Jan. 22, 2024. The video was published on Jan. 23, 2024.\", start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n'), Document(id_='aba45f22-8cbb-4309-8dc3-bf6f1b88bfc4', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text='\">photolithography machines</a></p><p>Different types of semiconductors perform different roles. The key types are logic chips, which interpret and perform instructions; memory chips, which store information; and analog chips, which convert real-world data into digital data. Central processing and graphics processing units are the most recognizable logic chips due to their inclusion in the laptops and desktops that normal people interact with at home. However, field-programmable gate arrays and application-specific integrated circuits are key sources of revenue for chip manufacturers.', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n')]\n",
      "========================\n",
      "\n",
      "Response: Here are some recent news highlights on semiconductors:\n",
      "\n",
      "1. The global semiconductor market is expected to reach a valuation of $588 billion in 2024, indicating a growth of 13.1%. This growth will be primarily fueled by the Memory sector, which is projected to surge to nearly $130 billion this year, up 40% from the previous year. [Source: World Semiconductor Trade Statistics (WSTS)](https://www.wsts.org/76/Recent-News-Release)\n",
      "\n",
      "2. VC investment in the semiconductor vertical has been on a downward trajectory. In 2023, it declined to a total of $10.3 billion, compared to $12.8 billion in 2022 and a peak of $16.1 billion in 2021. The future trends and opportunities in the semiconductor industry are explored in the latest Emerging Tech Research report. [Source: Emerging Tech Research]\n",
      "\n",
      "3. Researchers have made progress in graphene electronics research by finding a way to switch it on and off like silicon. Graphene is a promising material for semiconductors, but manipulating it without damaging its properties has been a challenge. By using a technique called doping, the researchers were able to measure the electronic properties of graphene without damaging it. [Source: Research Study]\n",
      "\n",
      "4. While companies like Nvidia, AMD, and Intel are well-known in the semiconductor industry, there are other companies playing an increasingly important role. These companies may not receive as much attention, but they contribute significantly to the industry. [Source: Market Analysis]\n",
      "\n",
      "5. Different types of semiconductors perform different roles. Logic chips interpret and perform instructions, memory chips store information, and analog chips convert real-world data into digital data. Central processing units (CPUs) and graphics processing units (GPUs) are examples of logic chips, while field-programmable gate arrays (FPGAs) and application-specific integrated circuits (ASICs) are key sources of revenue for chip manufacturers. [Source: Semiconductor Overview]\n",
      "\n",
      "Please note that these are just highlights, and for more detailed information, you can refer to the respective sources provided.\n"
     ]
    }
   ],
   "source": [
    "response = agent.chat(\"Tell me more about the recent news on semiconductors\")\n",
    "print(f\"Response: {str(response)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96c801b9-7f61-470b-9d05-c00622d5fbd7",
   "metadata": {},
   "source": [
    "### 2. Using `LoadAndSearchToolSpec`\n",
    "\n",
    "Here we wrap the `search_and_retrieve_documents` functionality with the `load_and_search_tool_spec`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a017cc61-1696-4a03-8d09-a628f9049cfd",
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.tools.tool_spec.load_and_search.base import LoadAndSearchToolSpec\n",
    "\n",
    "# The search_and_retrieve_documents tool is the third in the tool list, as seen above\n",
    "search_and_retrieve_docs_tool = exa_tool.to_tool_list(\n",
    "    spec_functions=[\"search_and_retrieve_documents\"]\n",
    ")[0]\n",
    "date_tool = exa_tool.to_tool_list(spec_functions=[\"current_date\"])[0]\n",
    "wrapped_retrieve = LoadAndSearchToolSpec.from_defaults(search_and_retrieve_docs_tool)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80b47437-8f6d-4e94-97ca-4e35f78336f2",
   "metadata": {},
   "source": [
    "Our wrapped retrieval tools separate loading and reading into separate interfaces. We use `load` to load the documents into the vector store, and `read` to query the vector store. Let's try it out again"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4f81bd3-a5b9-452c-93f4-91d16c4c0df1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Exa Tool] Autoprompt: Here's the best explanation for machine learning transformers:\n",
      "A transformer is a type of semi-supervised machine learning model that has revolutionized natural language processing tasks in recent years. It is primarily used with text data and has replaced recurrent neural networks in many applications. Transformers work on sequence data and can take an input sequence and generate an output sequence one element at a time. They consist of an encoder, which operates on the input sequence, and a decoder, which operates on the target output sequence during training and predicts the next item in the sequence. Transformers have become the de facto standard for NLP tasks and have also been applied in other fields such as computer vision and music generation.\n"
     ]
    }
   ],
   "source": [
    "wrapped_retrieve.load(\"This is the best explanation for machine learning transformers:\")\n",
    "print(wrapped_retrieve.read(\"what is a transformer\"))\n",
    "print(wrapped_retrieve.read(\"who wrote the first paper on transformers\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85be6977-c4e8-43a4-99be-3322d4b72b07",
   "metadata": {},
   "source": [
    "## Creating the Agent\n",
    "\n",
    "We now are ready to create an Agent that can use Metaphors services to it's full potential. We will use our wrapped read and load tools, as well as the `get_date` utility for the following agent and test it out below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a893f26-dbb6-4b72-9795-702eaf749564",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Just pass the wrapped tools and the get_date utility\n",
    "agent = OpenAIAgent.from_tools(\n",
    "    [*wrapped_retrieve.to_tool_list(), date_tool],\n",
    "    verbose=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5835d058-da9c-4d42-9d2a-941c73b88a51",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\n",
    "    agent.chat(\n",
    "        \"Can you summarize everything published in the last month regarding news on\"\n",
    "        \" superconductors\"\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7ee91ca-6730-4fdd-8189-ac21022f34f1",
   "metadata": {},
   "source": [
    "We asked the agent to retrieve documents related to superconductors from this month. It used the `get_date` tool to determine the current month, and then applied the filters in Metaphor based on publication date when calling `search`. It then loaded the documents using `retrieve_documents` and read them using `read_retrieve_documents`.\n",
    "\n",
    "We can make another query to the vector store to read from it again, now that the articles are loaded:"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "llama_hub_jeffzwang",
   "language": "python",
   "name": "llama_hub_jeffzwang"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
